//
//							Disposal.h
//

#ifndef __NEWA_DISPOSAL_H
#define __NEWA_DISPOSAL_H

#pragma message( "INCLUDING FILE: " __FILE__ )

#include "Base.h"
#include "NativeWindow.h"

#include <loki/SmartPtr.h>

namespace newa
{
	class WidgetElement;

	class Disposal
	{
	public:

		Disposal( WidgetElement& we )
			: m_linked_elem( &we )
		{}

		PixBuf& pixBuf()
		{
			return m_pbuf;
		}

		virtual void repaint() = 0; // notifies system that model changed

		virtual Point winPos() const = 0;

		virtual Point childPos() const = 0;

		virtual bool isWindowOwner() const = 0;

		virtual void dispose( Disposal& ) = 0;
	

		WidgetElement& linkedElem()
		{
			return *m_linked_elem;
		}

		const WidgetElement& linkedElem() const
		{
			return *m_linked_elem;
		}

		void flushPixBuf()
		{
			//rect( rect() );
			//m_pbuf.rect( Rect( winPos(), rect().size() ) ); // moved to the dispather
			NativeWindow * w = window();
			if( w != 0 )
				w->flushPixBuf( m_pbuf );
		}

		virtual NativeWindow * window() const = 0;

		virtual ~Disposal() 
		{}

	protected:
		void pixBufRect( const Rect& r )
		{
			m_pbuf.rect( r );
		}

	private:
		WidgetElement * m_linked_elem;
		PixBuf			m_pbuf;

		virtual Rect rect() const = 0;
		virtual void rect( const Rect& r ) = 0;

		friend class WidgetElement;
		
		template < typename DisposalT > 
		friend void Settle( Loki::SmartPtr<WidgetElement> child, Loki::SmartPtr<WidgetElement> parent, int, int );
	};

	namespace Disposals 
	{
		/************************************************************************/
		/*	Void				                                                */
		/************************************************************************/
		class Void : public Disposal
		{
		public:

			Void( WidgetElement& we )
				: Disposal( we )
			{}

			virtual void repaint()
			{}


			virtual bool isWindowOwner() const
			{
				return false;
			}

			virtual void dispose( Disposal& )
			{}

			virtual Point winPos() const
			{
				return Point( 0, 0 );
			}

			virtual Point childPos() const
			{
				return Point( 0, 0 );
			}

		protected:
			virtual NativeWindow * window() const
			{ 
				return 0;
			}

		private:
			virtual Rect rect() const
			{
				return Rect();
			}

			virtual void rect( const Rect& r ) 
			{}
		};
	}
}

#endif
